package com.xin.view;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;

import com.xin.view.libandroidremotecontrolview.R;

/**
 * https://www.jianshu.com/p/207ea78f1634
 * Created by zxd on 2016/6/27.
 */
public class DiskMenuView extends View {


    OnChangeStateListener mChangeStateListener = null;
    int itemAngle;/*每个格的角度*/
    GestureDetector detector;
    boolean isShrike;
    //按下时的X，Y坐标
    private int mArea = -1;
    //内圆边框的宽度
    private float innerCircleWidth;
    //外围圆的边框的宽度
    private float outerCircleWidth;
    //画笔对象
    private Paint paintLine;
    private Paint paintText;
    private Paint paintClick;
    /*共分多少格*/
    private int cellNum = 4;
    /*开始的角度*/
    private int startAngle = 0;
    /*显示在中间的文本*/
    private String[] strArr;
    private float widthOrigin, heightOrigin;
    private int colorCircle = 0xFFD8D9D9, colorLine, colorBg, colorStr;
    private float outerCircleRadius, innerCircleRadius, shrikeCircleRadius;
    private DiskMenuViewOnGestureListener gestureListener;
    private Bitmap imgDir;
    private boolean showCenter, showSeparateLine;
    private float separateWidth;
    private float centerCircleWidthRate, shrikeCircleWidthRate;
    private Bitmap imgCenter;
    private boolean autoShrink; /*是否自动收缩*/
    private int autoShrinkDelay; /*自动收缩的延迟*/
    private Handler handler;
    private AutoShrikeRunnable shrikeRunnable;
    private int centerX, centerY;

    public DiskMenuView(Context context) {
        this(context, null);
    }

    public DiskMenuView(Context context, AttributeSet attributeSet) {
        this(context, attributeSet, 0);
    }

    public DiskMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttr(context, attrs);
        init();
        initListener();
    }

    private boolean hasInitViewFinish;

    private void initListener() {
        getViewTreeObserver()
                .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        if (widthOrigin != 0 && heightOrigin != 0 && !hasInitViewFinish) {
                            log("onGlobalLayout() called");
                            hasInitViewFinish = true;
                            /*第一次时只执行一次*/
//                            initViewFinished();
                        }
                    }
                });

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            getViewTreeObserver()
                    .addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
                        @Override
                        public void onDraw() {
                            log("onDraw() called");
                        }
                    });
        }
    }


    private void initAttr(Context context, AttributeSet attrs) {
        TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.DiskMenuView);
        cellNum = t.getInt(R.styleable.DiskMenuView_DiskMenuView_CellNum, 4);
        startAngle = t.getInt(R.styleable.DiskMenuView_DiskMenuView_StartAngle, 0);
        autoShrinkDelay = t.getInt(R.styleable.DiskMenuView_DiskMenuView_AutoShrinkDelay, 3000);
        Drawable _imgDir = t.getDrawable(R.styleable.DiskMenuView_DiskMenuView_ImgDir);
        Drawable _imgCenter = t.getDrawable(R.styleable.DiskMenuView_DiskMenuView_ImgCenter);
        showCenter = t.getBoolean(R.styleable.DiskMenuView_DiskMenuView_ShowCenter, true);
        autoShrink = t.getBoolean(R.styleable.DiskMenuView_DiskMenuView_AutoShrink, false);
        showSeparateLine = t.getBoolean(R.styleable.DiskMenuView_DiskMenuView_ShowSeparateLine, true);
        colorLine = t.getColor(R.styleable.DiskMenuView_DiskMenuView_LineColor, 0xFFD8D9D9);
        colorBg = t.getColor(R.styleable.DiskMenuView_DiskMenuView_BgColor, Color.WHITE);
        colorStr = t.getColor(R.styleable.DiskMenuView_DiskMenuView_StrColor, Color.BLACK);
        colorCircle = t.getColor(R.styleable.DiskMenuView_DiskMenuView_CircleColor, 0xFF000000);
        centerCircleWidthRate = t.getFloat(R.styleable.DiskMenuView_DiskMenuView_InnerCircleWidthRate, 0.3f);
        shrikeCircleWidthRate = t.getFloat(R.styleable.DiskMenuView_DiskMenuView_ShrikeCircleWidthRate, 0.2f);
        String _strArr = t.getString(R.styleable.DiskMenuView_DiskMenuView_StrArr);
        if (_strArr != null && _strArr.split(",").length >= cellNum) {
            strArr = _strArr.split(",");
        }
        if (_imgDir != null) {
            imgDir = ((BitmapDrawable) _imgDir).getBitmap();
        }
        if (_imgCenter != null) {
            imgCenter = ((BitmapDrawable) _imgCenter).getBitmap();
        }
        t.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        log("onMeasure() called with: widthMeasureSpec = [" + widthMeasureSpec + "], heightMeasureSpec = [" + heightMeasureSpec + "]");
        if (widthOrigin == 0 || heightOrigin == 0) {
            /*会调用多次 值不一样 保存第一次 原始设置的值*/
            int w = getMeasuredWidth();
            int h = getMeasuredHeight();
            this.widthOrigin = w;
            this.heightOrigin = h;
            centerX = getMeasuredWidth() / 2;
            centerY = getMeasuredHeight() / 2;
            outerCircleRadius = Math.min(centerX, centerY) - outerCircleWidth;
            innerCircleRadius = outerCircleRadius * centerCircleWidthRate;
            shrikeCircleRadius = outerCircleRadius * shrikeCircleWidthRate;
            setShrike(autoShrink);
        }
    }

    private void init() {
        log("init() called");
        /*否则paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)会画不出来*/
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        float density = getResources().getDisplayMetrics().density;
        innerCircleWidth = density * 5;
        outerCircleWidth = density * 6;
        separateWidth = density * 5;

        paintLine = new Paint();
        itemAngle = 360 / cellNum;
        paintText = new Paint();
        paintText.setAntiAlias(true);
        paintText.setTextSize(density * 12);
        paintText.setColor(colorStr);
        paintText.setTextAlign(Paint.Align.CENTER);
        paintClick = new Paint();
        paintClick.setColor(colorCircle);
        gestureListener = new DiskMenuViewOnGestureListener();
        detector = new GestureDetector(getContext(), gestureListener);
        handler = new Handler();
        shrikeRunnable = new AutoShrikeRunnable();
    }

    public void setChangeStateListener(OnChangeStateListener changeStateListener) {
        mChangeStateListener = changeStateListener;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isShrike) {
            drawShrike(canvas);
        } else {
            drawExtend(canvas);
        }
    }

    /**
     * 伸展时的绘制
     *
     * @param canvas
     */
    private void drawExtend(Canvas canvas) {
        paintLine.setAntiAlias(true);
        drawCircle(canvas); /*画圆*/
        drawOnclikColor(canvas); /*画背景选择器*/
        drawLine(canvas); /*画直线*/
        drawText(canvas); /*画文字*/
    }

    /**
     * 收缩时的绘制 画个半透明的圆
     *
     * @param canvas
     */
    private void drawShrike(Canvas canvas) {
        log("drawShrike() called with: canvas = [" + canvas + "]");
        /*半透明白底层圆*/
        float circleRadius = this.shrikeCircleRadius;
        paintLine.setColor(colorLine);
        paintLine.setAlpha(80);
        paintLine.setStyle(Paint.Style.FILL);
        canvas.drawCircle(circleRadius, circleRadius, circleRadius, paintLine);
        /*边框*/
        paintLine.setColor(colorLine);
        paintLine.setAlpha(255);
        paintLine.setStrokeWidth(innerCircleWidth);
        paintLine.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(circleRadius, circleRadius, circleRadius - innerCircleWidth / 2, paintLine);
    }

    //写文字
    private void drawText(Canvas canvas) {
        Matrix matrix = new Matrix();
        Paint.FontMetricsInt fontMetrics = paintText.getFontMetricsInt();
        float centerRadius = (outerCircleRadius + innerCircleRadius) / 2;
//        canvas.drawPoints(new float[]{centerX,centerY},paintText);
        for (int i = 0; i < cellNum; i++) {
//            paintText.setColor(i == 0 ? Color.RED : Color.GREEN);
            int _itemStartAngle = itemAngle * i + startAngle;
            int _itemEndAngle = _itemStartAngle + itemAngle;
            int _averageAngle = (_itemEndAngle + _itemStartAngle) / 2;
            float textX = (float) (centerX + Math.cos(_averageAngle * Math.PI / 180) * centerRadius);
            float texty = (float) (centerY + Math.sin(_averageAngle * Math.PI / 180) * centerRadius);
//            canvas.drawPoints(new float[]{textX,texty},paintText);
            /*基线的位置*/
            int baseline = (int) (texty - (fontMetrics.bottom + fontMetrics.top) / 2);
            if (strArr != null && strArr.length >= i + 1) {
                String text = strArr[i + 1];
                canvas.drawText(text, textX, baseline, paintText);
            }
            if (imgDir != null) {
                matrix.reset();
                matrix.setRotate(_averageAngle, imgDir.getWidth() / 2, imgDir.getHeight() / 2);
                matrix.postTranslate(textX - imgDir.getWidth() / 2, texty - imgDir.getHeight() / 2); /*平移要最后*/
                canvas.drawBitmap(imgDir, matrix, new Paint());
            }
        }
        if (showCenter) {
            int baseline = (int) (centerY - (fontMetrics.bottom + fontMetrics.top) / 2);
            if (strArr != null && strArr.length >= 0) {
                String text = strArr != null ? strArr[0] : String.valueOf(0);
                canvas.drawText(text, centerX, baseline, paintText);
            }
            if (imgDir != null) {
                matrix.reset();
                matrix.postTranslate(centerX - imgCenter.getWidth() / 2, centerY - imgCenter.getHeight() / 2); /*平移要最后*/
                canvas.drawBitmap(imgCenter, matrix, new Paint());
            }
        }

    }

    //画圆
    private void drawCircle(Canvas canvas) {
        paintLine.setColor(colorBg);
        float width = outerCircleRadius - innerCircleRadius;
        paintLine.setStrokeWidth(width);
        paintLine.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(centerX, centerY, width / 2 + innerCircleRadius, paintLine);

        paintLine.setColor(colorCircle);
        paintLine.setStrokeWidth(outerCircleWidth);
        paintLine.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(centerX, centerY, outerCircleRadius, paintLine);

        paintLine.setColor(colorCircle);
        paintLine.setStrokeWidth(innerCircleWidth);
        paintLine.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(centerX, centerY, innerCircleRadius, paintLine);

        if (showCenter) {
            paintLine.setColor(colorBg);
            paintLine.setStyle(Paint.Style.FILL);
            canvas.drawCircle(centerX, centerY, innerCircleRadius, paintLine);
        }
    }

    //画直线
    private void drawLine(Canvas canvas) {


        Paint paintLine = new Paint();
        paintLine.setStrokeWidth(separateWidth);
        float startOffset = 0, endOffset = 0;
        if (showSeparateLine) {
            paintLine.setColor(colorLine);
            startOffset = outerCircleWidth / 2;
            endOffset = innerCircleWidth / 2;
        } else {
            paintLine.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            startOffset = -outerCircleWidth / 2;
            endOffset = innerCircleWidth / 2;
        }
        for (int i = 0; i < cellNum; i++) {
//            paintLine.setColor(i == 0 ? Color.RED : Color.GREEN);
            double v = (itemAngle * i + startAngle) * Math.PI / 180;
            double sinItem = Math.sin(v);
            double cosItem = Math.cos(v);
            canvas.drawLine((int) (centerX + (cosItem * (outerCircleRadius - startOffset))),
                    (int) (centerY + (sinItem * (outerCircleRadius - startOffset))),
                    (int) (centerX + (cosItem * (innerCircleRadius + endOffset))),
                    (int) (centerY + (sinItem * (innerCircleRadius + endOffset))),
                    paintLine);
        }
//        paintLine.setXfermode(null);
    }

    /**
     * 设置收缩是显示一个点
     *
     * @param isShrike
     */
    public void setShrike(boolean isShrike) {
        log("setShrike() called with: isShrike = [" + isShrike + "] " + this.isShrike);
        if (this.isShrike == isShrike) {
            return;
        }
        this.isShrike = isShrike;
        if (!isShrike) { /*伸展的直接重设布局*/
            setLayoutParams((int) widthOrigin, (int) heightOrigin);
        } else { /*收缩的动画*/
            final float startX = outerCircleRadius;
            final float endX_ = outerCircleRadius * shrikeCircleWidthRate;
            ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
            valueAnimator.setDuration(1000);
            valueAnimator.setInterpolator(new LinearInterpolator());
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {

                    float value = (float) animation.getAnimatedValue();
                    /*1->0*/
                    float _x = (endX_ - startX) * value + startX;
                    shrikeCircleRadius = _x; /*圆的半径 动态变化的*/
                    invalidate();
                }
            });
            valueAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    int v = (int) (shrikeCircleRadius * 2);
                    setLayoutParams(v, v);
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });
            valueAnimator.start();
        }
    }

    /**
     * @param width
     * @param height
     */
    private void setLayoutParams(int width, int height) {
        invalidate(); //不卡
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
        layoutParams.width = width;
        layoutParams.height = height;
        setLayoutParams(layoutParams);  //会有些卡
        if (!isShrike) {
        }


    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        detector.onTouchEvent(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                handler.removeCallbacks(shrikeRunnable);
                mArea = judgeArea(event.getX(), event.getY());
                if (mArea >= 0 && !isShrike) { /*大于0且伸展时*/
                    invalidate();
                    log("mChangeStateListener->" + mArea);
                  /*  if (mChangeStateListener != null && mArea >= 0) {
                        mChangeStateListener.onChangeState(mArea);
                    }*/
                }

                break;
            case MotionEvent.ACTION_UP:
                if (autoShrink) {
                    handler.postDelayed(shrikeRunnable, autoShrinkDelay);
                }
                if (mArea >= 0) {
                    mArea = -1;
                    invalidate();
                }
                if (isShrike) {
                    setShrike(false);
                } else {
                    gestureListener.onTouchUp(event);
                }

                break;
            default:
                break;
        }

        return true;
    }

    //触摸事件 即点击事件的处理

    //判断区域
    private int judgeArea(float x, float y) {
        if (isShrike) {
//            if (x <= shrikeCircleRadius && y <= shrikeCircleRadius) {
            return 0;
//            }
        } else {
            //判断是是否在大圆内
            if ((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY) <= outerCircleRadius * outerCircleRadius) {
                //判断是否在小圆内
                float v = 0;
                v = innerCircleRadius * innerCircleRadius;
                if ((x - centerX) * (x - centerX) + (y - centerY) * (y - centerY) > v) {
                    x = x - centerX;
                    y = centerY - y;
                    float tan = y / x;
                    double angle = 0;
                    double mathAngle = Math.atan(Math.abs(tan)) * 180 / Math.PI;
                    if (x >= 0 && y >= 0) { //一象限
                        angle = mathAngle;
                    } else if (x <= 0 && y >= 0) { //二角限
                        angle = 180 - mathAngle;
                    } else if (x <= 0 && y <= 0) {//三
                        angle = 180 + mathAngle;
                    } else if (x >= 0 && y <= 0) { //四
                        angle = 360 - mathAngle;
                    }
                    log("judgeArea->" + angle);
                    int area = (int) Math.ceil((360 - (angle + startAngle)) / itemAngle);
                    if (area > cellNum) {
                        area = area - cellNum;
                    }
                    return area;
                } else {
                    return 0;
                }
            }
        }
        return -1;
    }

    private void log(String t) {
        Log.d("DiskMenuView", t);
    }

    /**
     * 点击的时候绘制深色的扇形
     *
     * @param canvas
     */
    private void drawOnclikColor(Canvas canvas) {
        if (mArea == -1) { //未选中
            return;
        } else if (mArea == 0) { //中心区域
            if (showCenter) {
                paintClick.setStrokeWidth(0);
                paintClick.setStyle(Paint.Style.FILL);
                canvas.drawCircle(centerX, centerY, innerCircleRadius, paintClick);
            }
            return;
        } else {
            paintClick.setColor(colorCircle);
            paintClick.setStyle(Paint.Style.STROKE);
            float v = outerCircleRadius - innerCircleRadius;
            paintClick.setStrokeWidth(v);
            float _width = v / 2 + innerCircleRadius;
            RectF oval = new RectF(centerX - _width,
                    centerY - _width,
                    centerX + _width,
                    centerY + _width);

            canvas.drawArc(oval, (mArea - 1) * itemAngle + startAngle, itemAngle, false, paintClick);
        }

    }

    //定义接口
    public static abstract class OnChangeStateListener {
        /**
         * @param area 0 中心点 1是 1号位置 2号位置
         */
        public void onChangeState(int area) {
        }

        public void onChangeStateContinue(int area, boolean isDown) {
        }

        public void onChangeStateLongPress(int area) {
        }
    }

    /**
     * 自动收缩
     */
    private class AutoShrikeRunnable implements Runnable {
        @Override
        public void run() {
            setShrike(true);
        }
    }

    private class DiskMenuViewOnGestureListener implements GestureDetector.OnGestureListener {
        @Override
        public boolean onDown(MotionEvent event) {
            if (!checkCallback()) {
                return false;
            }
            int _mArea = judgeArea(event.getX(), event.getY());
            if (mChangeStateListener != null && _mArea >= 0) {
                mChangeStateListener.onChangeStateContinue(_mArea, true);
                return true;
            }
            return false;
        }

        private boolean checkCallback() {
            return !isShrike;
        }

        @Override
        public void onShowPress(MotionEvent e) {

        }

        /**
         * 快速单击 抬起时
         *
         * @param event
         * @return
         */
        @Override
        public boolean onSingleTapUp(MotionEvent event) {
            if (!checkCallback()) {
                return false;
            }
            int _mArea = judgeArea(event.getX(), event.getY());
            if (mChangeStateListener != null && _mArea >= 0) {
                mChangeStateListener.onChangeState(_mArea);
            }
            return false;
        }

        /**
         * 按下事件时
         *
         * @param event
         */
        public void onTouchUp(MotionEvent event) {
            if (!checkCallback()) {
                return;
            }
            int _mArea = judgeArea(event.getX(), event.getY());
            if (mChangeStateListener != null && _mArea >= 0) {
                mChangeStateListener.onChangeStateContinue(_mArea, false);
            }
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return false;
        }

        @Override
        public void onLongPress(MotionEvent event) {
            if (!checkCallback()) {
                return;
            }
            int _mArea = judgeArea(event.getX(), event.getY());
            if (mChangeStateListener != null && _mArea >= 0) {
                mChangeStateListener.onChangeStateLongPress(_mArea);
            }

        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            return false;
        }


    }
}